<?php
/**
 * Created by PhpStorm.
 * User: tairy
 * Date: 28/05/2018
 * Time: 17:34
 */

namespace Core\Common\Util;

use Core\Common\Base\Config;
use Core\Common\Route\Request;

/**
 * 工具类
 */
class Utils
{
    /**
     * 从jwt里获取里获取用户uid
     * @param string $jwtToken
     * @return bool|mixed
     */
    public static function getUserInfoFromJwtToken($jwtToken = '', $needCheck = true)
    {
        if (substr($jwtToken, 0, 7) != 'Bearer ') {
            return false;
        }

        $jwtToken = substr($jwtToken, 7);
        $rawArray = explode('.', $jwtToken);
        if (count($rawArray) != 3) {
            return false;
        }

        $signData = self::urlSafeB64Decode($rawArray[1]);
        if (!$needCheck) {
            return json_decode($signData, true);
        }

        $rawSign = $rawArray[2];
        $jwtKey = Config::getConfig()->application->jwtkey;
        $nowSign = hash_hmac('SHA256', $rawArray[0] . '.' . $rawArray[1], $jwtKey, true);
        $nowSign = self::urlSafeB64Decode($nowSign);
        if ($nowSign == $rawSign) {
            return json_decode($signData, true);
        }
        return false;
    }

    /**
     * 对url做base64 decode
     * @param $input
     * @return bool|string
     */
    public static function urlSafeB64Decode($input)
    {
        $remainder = strlen($input) % 4;
        if ($remainder) {
            $padLen = 4 - $remainder;
            $input .= str_repeat('=', $padLen);
        }
        return base64_decode(strtr($input, '-_', '+/'));
    }

    /**
     * 对url做base64 encode
     * @param $input
     * @return mixed
     */
    public static function urlSafeB64Encode($input)
    {
        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
    }

    /**
     * 获取请求头信息
     * @return array|false
     */
    public static function getAllHeaders($k = null)
    {
        if (function_exists('getallheaders')) {
            $hs = getallheaders();
            if ($k) {
                return isset($hs[$k]) ? $hs[$k] : null;
            }
            return $hs;
        }

        $headers = [];
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) != 'HTTP_') {
                continue;
            }

            $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
            if ($k == $key) {
                return $value;
            }

            $headers[$key] = $value;
        }
        return $headers;
    }

    /**
     * 获取数组里指定的key,如果没有此key则返回指定默认值
     * @param $arr
     * @param $key
     * @param array $defaultValue
     * @return array
     */
    public static function getArrayKeyGracefully($arr, $key, $defaultValue = [])
    {
        if (empty($arr)) {
            return $defaultValue;
        }

        if (isset($arr[$key])) {
            return is_array($arr[$key]) ? $arr[$key] : $defaultValue;
        }

        return $defaultValue;
    }

    /**
     * 批量获取数组里指定key
     * @param $arr
     * @param $keys
     * @return array
     */
    public static function fetchArrayRowsByKey($arr, $keys)
    {
        if (empty($arr)) {
            return $arr;
        }

        $ret = [];
        foreach ($keys as $k) {
            if (isset($arr[$k])) {
                $ret[$k] = $arr[$k];
            }
        }

        return $ret;
    }

    /**
     * 取数组里指定列
     * @param $arr
     * @param $fs
     * @return array
     */
    public static function fetchArrayColumn($arr, $fs)
    {
        if (empty($arr)) {
            return [];
        }

        $tmp = array_map(function ($v) use ($fs) {
            return isset($v[$fs]) ? $v[$fs] : null;
        }, $arr);

        return array_filter($tmp);
    }

    /**
     * @return array|false|string
     */
    public static function getClientIp()
    {
        if (Request::server('HTTP_CLIENT_IP')) {
            return Request::server('HTTP_CLIENT_IP');
        } else {
            if (Request::server('HTTP_X_FORWARDED_FOR')) {
                return Request::server('HTTP_X_FORWARDED_FOR');
            } 
            if (Request::server('X_FORWARDED_FOR')) {
                return Request::server('X_FORWARDED_FOR');
            } 
            if (Request::server('REMOTE_ADDR')) {
                return Request::server('REMOTE_ADDR');
            } 
            if (Request::server('HTTP_X_REAL_IP')) {
                return Request::server('HTTP_X_REAL_IP');
            } 
            if (Request::server('X_REAL_IP')) {
                return Request::server('X_REAL_IP');
            } 
        }
        return 'Unknown';
    }


    /**
     * @param null $server
     * @return mixed|string
     */
    public static function getIpAddress($server = null)
    {
        if ($server && $server instanceof \swoole_server && $server->host != '0.0.0.0') {
            return $server->host;
        }
        return Helper::getIpAddress();
    }
}
